#pragma once
#include <iostream>
#include <string>
#include <jsoncpp/json/json.h>

/*  读到的请求无法保证是一个完整的，所以需要对字符串流进行分析，最后再读取
协议的报头和报文的完整格式——"len"\r\n"{json}"\r\n
    len：有效载荷的长度-json串的长度
    第一个:\r\n -区分len和json串
    第二个:方便打印Debug
*/
static const std::string sep = "\r\n";

/// @brief 添加报头
/// @param jsonstr json串
/// @return 报文的完整格式："len"\r\n"{json}"\r\n
std::string EnCode(const std::string &jsonstr)
{
    int len = jsonstr.size();
    std::string lenstr = std::to_string(len);
    return lenstr + sep + jsonstr + sep;
}

/// @brief 在网络字节流中提取出完整的报文,并删除头部已经解析的报文
/// @param pagestream 
/// @return 报文的完整格式："len"\r\n"{json}"\r\n
std::string DeCode(std::string &pagestream)
{
    //找分隔符
    auto pos = pagestream.find(sep);
    if(pos == std::string::npos)
        return std::string();
    //解析len
    std::string lenstr = pagestream.substr(0,pos);
    size_t len = std::stoi(lenstr);
    //检查整体长度
    size_t total = lenstr.size() + len + 2 * sep.size();
    if(pagestream.size() < total)
        return std::string();
    //到这里，字节流中有至少一个完整报文
    std::string jsonstr = pagestream.substr(pos + sep.size(),len);
    //删除头部
    pagestream.erase(0,total);
    return jsonstr;
}

// 客户端发送的请求
class Request
{
public:
    Request()
    {
    }

    Request(int x, int y, char oper)
        : _x(x), _y(y), _oper(oper)
    {
    }

    bool Serialize(std::string *out)
    {
        Json::Value root;
        root["x"] = _x;
        root["y"] = _y;
        root["oper"] = _oper;
        Json::FastWriter writer;

        // Json::StyledWriter writer;
        std::string s = writer.write(root);

        *out = s;
        return true;
    }

    // true if the document was successfully parsed, false if an error occurred.
    bool Deserialize(const std::string &in)
    {
        Json::Value root;
        Json::Reader reader;
        bool res = reader.parse(in, root);
        if (!res)
            return false;

        _x = root["x"].asInt();
        _y = root["y"].asInt();
        _oper = root["oper"].asInt();

        return true;
    }

    ~Request()
    {
    }
    int X()
    {
        return _x;
    }
    int Y()
    {
        return _y;
    }
    char Oper()
    {
        return _oper;
    }
private:
    int _x;
    int _y;
    char _oper;
};

// 服务端回应的结果
class Response
{
public:
    Response():_result(0),_code(0),_desc("Success")
    {
    }
   
    bool Serialize(std::string *out)
    {
        Json::Value root;
        root["result"] = _result;
        root["code"] = _code;
        root["desc"] = _desc;

        Json::FastWriter writer;
        // Json::StyledWriter writer;
        std::string s = writer.write(root);

        *out = s;
        return true;
    }
    bool Deserialize(const std::string &in)
    {
        Json::Value root;
        Json::Reader reader;
        bool res = reader.parse(in, root);
        if (!res)
            return false;

        _result = root["result"].asInt();
        _code = root["code"].asInt();
        _desc = root["desc"].asString();

        return true;
    }
    ~Response()
    {
    }
    void SetResult(int result)
    {
        _result = result;
    }
    void SetCode(int code)
    {
        _code = code;
    }
    void SetDesc(const std::string& desc)
    {
        _desc = desc;
    }

private:
    int _result;       // 计算的结果
    int _code;         // 状态码 0：success 1：div zero 2：非法操作
    std::string _desc; // 错误的具体描述
};
